home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
comm
/
mail
/
Mutt089src.lha
/
Mutt-0.89i-AMIGA
/
src
/
edit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-28
|
11KB
|
446 lines
/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* Close approximation of the mailx(1) builtin editor for sending mail. */
#include "mutt.h"
#include "mutt_curses.h"
#include "send.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
/*
* SLcurses_waddnstr() can't take a "const char *", so this is only
* declared "static" (sigh)
*/
static char EditorHelp[] = "\
~~ insert a line begining with a single ~\n\
~b users add users to the Bcc: field\n\
~c users add users to the Cc: field\n\
~f messages include messages\n\
~F messages same as ~f, except also include headers\n\
~h edit the message header\n\
~m messages include and quote messages\n\
~M messages same as ~m, except include headers\n\
~p print the message\n\
~q write file and quit editor\n\
~r file read a file into the editor\n\
~t users add users to the To: field\n\
~u recall the previous line\n\
~v edit message with the $visual editor\n\
~w file write message to file\n\
~x abort changes and quit editor\n\
~? this message\n\
. on a line by itself ends input\n";
static char **
be_snarf_data (FILE *f, char **buf, int *bufmax, int *buflen, int offset,
int bytes, int prefix)
{
char tmp[HUGE_STRING];
char *p = tmp;
int tmplen = sizeof (tmp);
tmp[sizeof (tmp) - 1] = 0;
if (prefix)
{
strfcpy (tmp, Prefix, sizeof (tmp));
tmplen = strlen (tmp);
p = tmp + tmplen;
tmplen = sizeof (tmp) - tmplen;
}
fseek (f, offset, 0);
while (bytes > 0)
{
if (fgets (p, tmplen - 1, f) == NULL) break;
bytes -= strlen (p);
if (*bufmax == *buflen)
safe_realloc ((void **)&buf, sizeof (char *) * (*bufmax += 25));
buf[(*buflen)++] = safe_strdup (tmp);
}
if (buf) buf[*buflen] = NULL;
return (buf);
}
static char **
be_snarf_file (const char *path, char **buf, int *max, int *len)
{
FILE *f;
struct stat sb;
if ((f = fopen (path, "r")))
{
fstat (fileno (f), &sb);
buf = be_snarf_data (f, buf, max, len, 0, sb.st_size, 0);
fclose (f);
}
return (buf);
}
static int be_barf_file (const char *path, char **buf, int buflen)
{
FILE *f;
int i;
if ((f = fopen (path, "w")) == NULL)
{
addstr (strerror (errno));
addch ('\n');
return (-1);
}
for (i = 0; i < buflen; i++) fputs (buf[i], f);
if (fclose (f) == 0) return 0;
printw ("fclose: %s\n", strerror (errno));
return (-1);
}
static void be_free_memory (char **buf, int buflen)
{
while (buflen-- > 0)
free (buf[buflen]);
if (buf)
free (buf);
}
static char **
be_include_messages (char *msg, char **buf, int *bufmax, int *buflen,
int pfx, int inc_hdrs)
{
int offset, bytes, n;
char tmp[LONG_STRING];
while ((msg = strtok (msg, " ,")) != NULL)
{
n = atoi (msg);
if (n > 0 && n <= Context->msgcount)
{
n--;
/* add the attribution */
mutt_make_string (tmp, sizeof (tmp)-1, Attribution, Context->hdrs[n]);
strcat (tmp, "\n");
if (*bufmax == *buflen)
safe_realloc ((void **)&buf, sizeof (char *) * (*bufmax += 25));
buf[(*buflen)++] = safe_strdup (tmp);
bytes = Context->hdrs[n]->content->length;
if (inc_hdrs)
{
offset = Context->hdrs[n]->offset;
bytes += Context->hdrs[n]->content->offset - offset;
}
else
offset = Context->hdrs[n]->content->offset;
buf = be_snarf_data (Context->fp, buf, bufmax, buflen, offset, bytes,
pfx);
if (*bufmax == *buflen)
safe_realloc ((void **)&buf, sizeof (char *) * (*bufmax += 25));
buf[(*buflen)++] = safe_strdup ("\n");
}
else
printw ("%d: invalid message number.\n", n);
msg = NULL;
}
return (buf);
}
static void be_print_header (ENVELOPE *env)
{
char tmp[HUGE_STRING];
if (env->to)
{
addstr ("To: ");
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), env->to);
addstr (tmp);
addch ('\n');
}
if (env->cc)
{
addstr ("Cc: ");
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), env->cc);
addstr (tmp);
addch ('\n');
}
if (env->bcc)
{
addstr ("Bcc: ");
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), env->bcc);
addstr (tmp);
addch ('\n');
}
if (env->subject)
{
addstr ("Subject: ");
addstr (env->subject);
addch ('\n');
}
addch ('\n');
}
/* args:
* force override the $ask* vars (used for the ~h command)
*/
static void be_edit_header (ENVELOPE *e, int force)
{
char tmp[HUGE_STRING];
move (LINES-1, 0);
addstr ("To: ");
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), e->to);
if (!e->to || force)
{
if (mutt_enter_string ((unsigned char *) tmp, sizeof (tmp), LINES-1, 4, 0) == 0)
{
mutt_free_address (&e->to);
mutt_parse_adrlist (&e->to, tmp, "@");
e->to = mutt_expand_aliases (e->to);
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), e->to);
mvaddstr (LINES - 1, 4, tmp);
}
}
else
{
addstr (tmp);
}
addch ('\n');
if (!e->subject || force)
{
addstr ("Subject: ");
strfcpy (tmp, e->subject ? e->subject: "", sizeof (tmp));
if (mutt_enter_string ((unsigned char *) tmp, sizeof (tmp), LINES-1, 9, 0) == 0)
{
safe_free ((void **) &e->subject);
e->subject = safe_strdup (tmp);
}
addch ('\n');
}
if ((!e->cc && option (OPTASKCC)) || force)
{
addstr ("Cc: ");
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), e->cc);
if (mutt_enter_string ((unsigned char *) tmp, sizeof (tmp), LINES-1, 4, 0) == 0)
{
mutt_free_address (&e->cc);
mutt_parse_adrlist (&e->cc, tmp, "@");
e->cc = mutt_expand_aliases (e->cc);
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), e->cc);
mvaddstr (LINES - 1, 4, tmp);
}
addch ('\n');
}
if (option (OPTASKBCC) || force)
{
addstr ("Bcc: ");
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), e->bcc);
if (mutt_enter_string ((unsigned char *) tmp, sizeof (tmp), LINES-1, 5, 0) == 0)
{
mutt_free_address (&e->bcc);
mutt_parse_adrlist (&e->bcc, tmp, "@");
e->bcc = mutt_expand_aliases (e->bcc);
tmp[0] = 0;
rfc822_write_address (tmp, sizeof (tmp), e->bcc);
mvaddstr (LINES - 1, 5, tmp);
}
addch ('\n');
}
}
int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
{
char **buf = NULL;
int bufmax = 0, buflen = 0;
char tmp[LONG_STRING];
int abort = 0;
int done = 0;
int i;
char *p;
scrollok (stdscr, TRUE);
be_edit_header (msg->env, 0);
addstr ("(End message with a . on a line by itself)\n");
buf = be_snarf_file (path, buf, &bufmax, &buflen);
tmp[0] = 0;
while (!done)
{
if (mutt_enter_string ((unsigned char *) tmp, sizeof (tmp), LINES-1, 0, 0) == -1)
{
tmp[0] = 0;
continue;
}
addch ('\n');
if (tmp[0] == EscChar[0] && tmp[1] != EscChar[0])
{
/* remove trailing whitespace from the line */
p = tmp + strlen (tmp) - 1;
while (p >= tmp && ISSPACE (*p))
*p-- = 0;
p = tmp + 2;
SKIPWS (p);
switch (tmp[1])
{
case '?':
addstr (EditorHelp);
break;
case 'b':
mutt_parse_adrlist (&msg->env->bcc, p, "@");
msg->env->bcc = mutt_expand_aliases (msg->env->bcc);
break;
case 'c':
mutt_parse_adrlist (&msg->env->cc, p, "@");
msg->env->cc = mutt_expand_a